#include "DGL3Common.glsl"
#include "DGL3PickCommon.glsl"
#include "DGL3ProgramEnums.inc"

//-----------------------------------------

#ifdef VERTEX_SHADER

	layout(location = 0) in vec3 aPosition;
	layout(location = GE_VA_Transform) in ivec2 aAssigns;

	out vec2 screenPosition;

	void main(void)
	{
		gl_Position = GetModelMatrix(aAssigns.x) * vec4(aPosition, 1.0);
		vec4 screenPos4 = (uProjectionMatrix * uViewMatrix * GetModelMatrix(aAssigns.x)) * vec4(aPosition, 1.0);
		screenPosition = screenPos4.xy / screenPos4.w;
	}

#endif

//-----------------------------------------

#ifdef GEOMETRY_SHADER

	layout(lines) in; 
	layout(points, max_vertices = 1) out;

	uniform vec3 uRayOrigin;
	uniform vec3 uRayDirection;
	uniform vec2 uRayOrigin2d;
	uniform float uTolerance;

	in vec2 screenPosition[];		
	out vec3 ndcPos; 
	
	void main(void)
	{
		vec3 p1 = gl_in[0].gl_Position.xyz;
		vec3 p2 = gl_in[1].gl_Position.xyz;

		if ( LineSegmentIntersect2d(uRayOrigin2d, screenPosition[0], screenPosition[1], uTolerance) )
		{
			vec3 hitPoint;
			if (FindHitPointToLine3d(uRayOrigin, uRayDirection, p1, p2, hitPoint))
			{
				gl_Position = uProjectionMatrix * uViewMatrix * vec4( hitPoint, 1 );
				ndcPos = gl_Position.xyz / gl_Position.w;
							
				EmitVertex();
				EndPrimitive();			
			}			
		}		
	}

#endif

//-----------------------------------------

#ifdef FRAGMENT_SHADER

	in vec3 ndcPos;
	
	layout(location = 0) out vec4 fragColor;
	
	void main(void)
	{
		// convert ndcPos from range [-1;1] to range [0;1]
		fragColor = vec4( (ndcPos+1)/2, 0.0 );
	}

#endif

//-----------------------------------------

#ifdef RECT_TEST_VERTEX_SHADER

	layout(location = 0) in vec3 aPosition;
	layout(location = GE_VA_Transform) in ivec2 aAssigns;
	
	out vec2 pos2d;

	void main(void)
	{
		vec4 screenPos4 = (uProjectionMatrix * uViewMatrix * GetModelMatrix(aAssigns.x)) * vec4(aPosition, 1.0);
		pos2d = screenPos4.xy / screenPos4.w;
	}

#endif

#ifdef RECT_TEST_FRAGMENT_SHADER

	layout(location = 0) out vec4 fragColor;

	void main(void)
	{		
		fragColor = vec4( COLOR_INCREMENT, 0.0, 0.0, 1.0 );
	}

#endif

#ifdef RECT_TEST_GEOMETRY_SHADER

	layout(lines) in; 
	layout(points, max_vertices = 2) out;

	uniform vec2 uLeftBottom;
	uniform vec2 uRightTop;

	in vec2 pos2d[];
	
	void main(void)
	{
		gl_Position = TOTAL_POSITION; 
		EmitVertex();
		EndPrimitive();	
	
		int count = 0;
		if ( IsPointInsideRect( pos2d[0], uLeftBottom, uRightTop ) )
			count++;
		if ( IsPointInsideRect( pos2d[1], uLeftBottom, uRightTop ) )
			count++;

		if ( count > 0 )
		{
			if ( count == 2 )
				gl_Position = INSIDE_POSITION;
			else if ( count == 1 )
				gl_Position = INTERSECT_POSITION;
				
			EmitVertex();
			EndPrimitive();		
		}	
		else if ( SegmentRectangleIntersection2d( pos2d[0], pos2d[1], uLeftBottom, uRightTop ) )
		{
			gl_Position = INTERSECT_POSITION;
			EmitVertex();
			EndPrimitive();
		}
	}

#endif
